package model;
/**
 * A Player type Character. This Character is human controlled.
 * @author Alex Dinardo
 * @author Robert Gillespie
 *
 */
public class Player extends Character{
	
	/** The number of lives that a Player has. Zero Lives means game over.*/
	private int lives;
	
	/** Accumulative number of dots eaten over the course of a campaign. */
	private int dotsEatenTotal;
	
	/** The number of dots the player has eaten this life time. */
	private int dotsEatenThisLife;
	
	/** The number of moves the player has made in the game. */
	private int movesMade;
	
	/**
	 * Creates a new PLayer object and places it in the Maze.
	 * @param startTile The tile that the Player is placed in at the start of every level. 
	 * 					It is passed the constructor of the superclass Character.
	 * @param startLives The number of lives that the Player starts off with.
	 */
	public Player(Tile startTile, int startLives)
	{
		super(startTile);
		lives = startLives;
		dotsEatenTotal = 0;
		dotsEatenThisLife = 0;
		movesMade = 0;
	}
	
	/**
	 * Decrement's the number of lives this Player has and removes DEATH_POINTS
	 * number of points from the players score.
	 * @return True if the Player has lost his last life.
	 */
	public boolean loseLife()
	{
		this.lives--;
		dotsEatenThisLife = 0;
		return isDead();
	}
	
	/**
	 * Resets the counter for the player's dots eaten this life.
	 */
	public void resetDotsThisLife() {
		dotsEatenThisLife = 0;
	}
	
	/**
	 * Retrieves the number of lives this Player has.
	 * @return number of lives.
	 */
	public int getLives()
	{
		return this.lives;
	}
	
	/**
	 * Sets the players live to the specified value, given that
	 * it is positive
	 * @param lives	the number of lives for the player
	 */
	public void setLives(int lives)
	{
		if (lives >= 0) {
			this.lives = lives;
		}
	}
	
	/**
	 * Checks the number of lives this Player has and determines if its zero.
	 * @return True if there are zero lives left.
	 */
	public boolean isDead()
	{
		return (lives == 0);
	}
	
	/**
	 * Sets a new Tile as the Character's current position, provided the tile
	 * is not null. If the tile is null, nothing occurs and false is returned.
	 * @param newTile 
	 * @return True if successful.
	 */
	public boolean setTile (Tile newTile)
	{	
		this.getTile().clearDot();
		boolean returnVal = super.setTile(newTile);
		if(this.getTile().hasDot())this.dotsEatenThisLife++;
		this.getTile().clearDot();
		return returnVal;
	}

	/**
	 * Gets the running total of dots eaten during the current campaign.
	 * @return number of dots eaten
	 */
	public int getDotsEatenTotal() {
		return dotsEatenTotal;
	}

	/**
	 * Gets the number of dots eaten this life/level
	 * @return gets number of dots eaten
	 */
	public int getDotsEatenThisLife() {
		return dotsEatenThisLife;
	}
	
	/**
	 * Gets the running total of dots eaten overall.
	 * @return total number of dots eaten
	 */
	public int dotsEaten(){
		return this.dotsEatenTotal + this.dotsEatenThisLife;
	}

	/**
	 * Gets the total number of moves a player has made this campaign.
	 * @return moves made
	 */
	public int getMovesMade() {
		return movesMade;
	}
	
	/**
	 * Moves the Player one Tile in the desired Direction. If the new tile has 
	 * a dot the respective count will increment. If the player makes a succesful
	 * move the respective count will also increment.
	 * @param dir The Direction that the Character needs to move in.
	 * @return True if the move was a success. False if it failed (ie. there
	 * is no exit in the Direction.
	 */
	@Override
	public boolean move(Direction dir){
		boolean succesfulMove = super.move(dir);
		if(succesfulMove) this.movesMade++;
		return succesfulMove;
	}
	
	/**
	 * Should be called when ever a level is completed. This adds this lives running 
	 * total of dots eaten this life to the campaigns total. It also resets the number
	 * of dots for the current life.
	 */
	public void nextLevel(){
		this.dotsEatenTotal += this.dotsEatenThisLife;
		this.dotsEatenThisLife = 0;
	}
}
